~ chicken-core (master) /manual/Module (chicken process)
Trap1[[tags: manual]]2[[toc:]]34== Module (chicken process)56This module offers procedures for interacting with subprocesses.78Note:9Errors caused by underlying C calls that10change errno will produce a condition object with an {{errno}}11property, which can be accessed with12{{(get-condition-property <the-condition-object> 'exn 'errno)}}.1314=== Processes1516==== process-execute1718<procedure>(process-execute PATHNAME [ARGUMENT-LIST [ENVIRONMENT-ALIST]])</procedure>1920Replaces the running process with a new process image from the program21stored at {{PATHNAME}}, using the C library function {{execvp(3)}}.22If the optional argument {{ARGUMENT-LIST}} is given, then it should23contain a list of strings which are passed as arguments to the subprocess.24If the optional argument {{ENVIRONMENT-ALIST}} is supplied, then the library25function {{execve(2)}} is used, and the environment passed in26{{ENVIRONMENT-ALIST}} (which should be of the form {{(("<NAME>" . "<VALUE>") ...)}})27is given to the invoked process. Note that {{execvp(3)}} respects the28current setting of the {{PATH}} environment variable while {{execve(3)}} does not.2930This procedure never returns; it either replaces the process with a new one31or it raises an exception in case something went wrong executing the program.3233On Windows, these procedures all have an additional optional parameter34{{EXACT-FLAG}}, which defaults to {{#f}}. When {{#f}} is passed, any35argument string with embedded whitespace will be wrapped in36quotes. When {{#t}} no such wrapping occurs.373839==== process-fork4041<procedure>(process-fork [THUNK [KILLOTHERS?]])</procedure>4243Creates a new child process with the UNIX system call44{{fork()}}. In the parent process this procedure returns a process-object representing the child process45and in the child process {{process-fork}} returns {{#f}}.46If {{THUNK}} is given, then the child process calls it as a procedure47with no arguments and terminates. If {{THUNK}} is given and the48optional argument {{KILLOTHERS?}} is true, then kill all other49existing threads in the child process, leaving only the current thread50to run {{THUNK}} and terminate.5152'''NOTE''': On native Windows builds (all except cygwin), this53procedure is unimplemented and will raise an error.5455==== process-run5657<procedure>(process-run COMMANDLINE)</procedure><br>58<procedure>(process-run COMMAND ARGUMENT-LIST)</procedure>5960Creates a new child process. The process object representing the new process is returned.6162* The single parameter version passes the {{COMMANDLINE}} to the63system shell, so usual argument expansion can take place. Be careful64to properly quote arguments with the {{qs}} procedure to avoid shell65injection vulnerabilities.66* The multiple parameter version directly invokes the {{COMMAND}} with67the {{ARGUMENT-LIST}}, and is vastly preferred over the68single-parameter version because of its better safety.6970==== process-signal7172<procedure>(process-signal PROCESS [SIGNAL])</procedure>7374Sends {{SIGNAL}} to the process with the integer id or prcoess75object {{PROCESS}} using the76UNIX system call {{kill()}}. {{SIGNAL}} defaults to the value77of the variable {{signal/term}}.7879'''NOTE''': On native Windows builds (all except cygwin), this80procedure is unimplemented and will raise an error.8182==== process-spawn8384<procedure>(process-spawn MODE COMMAND [ARGUMENT-LIST [ENVIRONMENT-LIST [EXACT-FLAG]]])</procedure>8586Creates and runs a new process with the given {{COMMAND}} filename and87the optional {{ARGUMENT-LIST}} and {{ENVIRONMENT-LIST}}. {{MODE}}88specifies how exactly the process should be executed and must be one89or more of the {{spawn/...}} flags listed below.9091The {{EXACT-FLAG}}, default {{#f}}, controls quote-wrapping of92argument strings. When {{#t}} quote-wrapping is not performed.9394Returns:95* the exit status when synchronous96* a process object when asynchronous9798'''NOTE''': On all Unix-like builds (all except native MingW-based99Windows platforms), this procedure is unimplemented and will raise an100error.101102<constant>spawn/overlay</constant>103<constant>spawn/wait</constant>104<constant>spawn/nowait</constant>105<constant>spawn/nowaito</constant>106<constant>spawn/detach</constant>107108These variables contains special flags that specify the exact109semantics of {{process-spawn}}:110111* {{spawn/overlay}} replaces the current process with the new one.112* {{spawn/wait}} suspends execution of the current process until the spawned process returns.113* {{spawn/nowait}} does the opposite ({{spawn/nowaito}} is identical, according to the Microsoft documentation) and runs the process asynchronously.114* {{spawn/detach}} runs the new process in the background, without being attached to a console.115116117==== process-wait118119<procedure>(process-wait [PROCESS [NOHANG]])</procedure>120121Suspends the current process until the child process identifier by {{PROCESS}},122which should be a process object or an integer process id (pid),123has terminated using the UNIX system call124{{waitpid()}}. If {{PROCESS}} is not given, then this procedure125waits for any child process. If {{NOHANG}} is given and not126{{#f}} then the current process is not suspended. This procedure127returns three values:128129* {{PID}} or 0, if {{NOHANG}} is true and the child process has not terminated yet.130* {{#t}} if the process exited normally or {{#f}} otherwise.131* either the exit status, if the process terminated normally or the signal number that terminated/stopped the process.132133Note that suspending the current process implies that all threads134are suspended as well.135136The exit status and the flag indicating whether the process returned normally137are also stored in {{PROCESS}}, when given to be retrieved later, if desired.138139On Windows, {{process-wait}} always returns {{#t}} for a terminated140process and only the exit status is available. (Windows does not141provide signals as an interprocess communication method.)142143144==== process-sleep145146<procedure>(process-sleep SECONDS)</procedure>147148Puts the process to sleep for {{SECONDS}}. Returns either 0 if149the time has completely elapsed, or the number of remaining seconds,150if a signal occurred.151152153==== process154155<procedure>(process COMMANDLINE)</procedure><br>156<procedure>(process COMMAND ARGUMENT-LIST [ENVIRONMENT-ALIST ENCODING])</procedure>157158Creates a subprocess and returns a process object, with the input-, output- and159error ports stored in the object, which can be accessed using accessors described160below.161162* The single parameter version passes the string {{COMMANDLINE}} to the host-system's shell that163is invoked as a subprocess.164* The multiple parameter version directly invokes the {{COMMAND}} as a subprocess. The {{ARGUMENT-LIST}}165is directly passed, as is {{ENVIRONMENT-ALIST}}. These arguments have the same form as the ones of {{process-execute}}.166167{{ENCODING}} should be a symbol specifying the encoding to be168used for I/O operations, the default is {{utf-8}}. The encodings for169the returned in and output ports can be subsequently changed by170using the {{port-encoding}} setter.171172Not using the shell may be preferrable for security reasons.173174Once both the input- and output ports are closed, an implicit175{{waitpid(3)}} is done to wait for the subprocess to finish or to reap176a subprocess that has terminated. If the subprocess has not finished,177waiting for it will necessarily block all executing threads. The exit status178and whether the process exitted normally will be stored in the returned179process object to be retrieved later by the accessors described below,180if so desired.181182==== process*183184<procedure>(process* COMMANDLINE)</procedure><br>185<procedure>(process* COMMAND ARGUMENT-LIST [ENVIRONMENT-ALIST ENCODING])</procedure>186187Like {{process}} but returns 4 values: an input port from188which data written by the sub-process can be read, an output port from189which any data written to will be received as input in the sub-process,190the process-id of the started sub-process, and an input port from191which data written by the sub-process to {{stderr}} can be read.192193==== process?194==== process-id195==== process-exit-status196==== process-returned-normally?197==== process-input-port198==== process-output-port199==== process-error-port200201<procedure>(process? X)</procedure>202203Returns a boolean indicating whether {{X}} is a process object.204205<procedure>(process-id PROCESS)</procedure>206<procedure>(process-exit-status PROCESS)</procedure>207<procedure>(process-returned-normally? PROCESS)</procedure>208<procedure>(process-input-port PROCESS)</procedure>209<procedure>(process-output-port PROCESS)</procedure>210<procedure>(process-error-port PROCESS)</procedure>211212Accessors for process-object attributes. The ports values are only213defined for processes created with {{process}} or {{process*}} and represent214the input port from215which data written by the sub-process can be read, the output port from216which any data written to will be received as input in the sub-process217and the error port where to which the sub-process directs its error output.218Blocking reads and writes219to or from the ports returned by {{process}} only block the current220thread, not other threads executing concurrently.221222Standard error for the subprocess is linked up to the current223process's standard error (see {{process*}} if you want to reify224its standard error into a separate port).225226=== Shell commands227228The commands below are all string-based. This means you have to be229very careful to properly quote any arguments to subprocesses, to avoid230shell injection bugs which can lead to arbitrary code execution.231232You can quote arguments with the {{qs}} procedure, but it is strongly233recommended you use {{fork}} with {{process-execute}} or the234multi-argument versions of the {{process}}, {{process*}} or235{{process-run}} procedures.236237==== qs238239<procedure>(qs STRING [PLATFORM])</procedure>240241Escapes {{STRING}} suitably for passing to a shell command on {{PLATFORM}}.242{{PLATFORM}} defaults to the value of {{(build-platform)}} and indicates in243which style the argument should be quoted. On Windows systems, the string244is simply enclosed in double-quote ({{"}}) characters, on UNIXish systems,245characters that would have a special meaning to the shell are escaped246using backslash ({{\}}).247248249==== system250251<procedure>(system STRING)</procedure>252253Execute shell command. The functionality offered by this procedure254depends on the capabilities of the host shell. If the forking of a subprocess255failed, an exception is raised. Otherwise the return status of the256subprocess is returned unaltered.257258259On a UNIX system, that value is the raw return value of waitpid(2), which contains signal, core dump and exit status. It is 0 on success. To pull out the signal number or exit status portably requires POSIX calls, but in a pinch you can use something like this:260261<enscript highlight='scheme'>262;; Returns two values: #t if the process exited normally or #f otherwise;263;; and either the exit status, or the signal number if terminated via signal.264(define (process-status rc)265 (define (wait-signaled? x) (not (= 0 (bitwise-and x 127))))266 (define (wait-signal x) (bitwise-and x 127))267 (define (wait-exit-status x) (arithmetic-shift x -8))268 (if (wait-signaled? rc)269 (values #f (wait-signal rc))270 (values #t (wait-exit-status rc))))271272#;> (process-status (system "exit 42"))273#t27442275</enscript>276277==== system*278279<procedure>(system* STRING)</procedure>280281Similar to {{(system STRING)}}, but signals an error should the invoked282program return a nonzero exit status.283284=== Pipes285286==== call-with-input-pipe287==== call-with-output-pipe288289<procedure>(call-with-input-pipe CMDLINE PROC [MODE])</procedure><br>290<procedure>(call-with-output-pipe CMDLINE PROC [MODE])</procedure>291292Call {{PROC}} with a single argument: a input- or output port293for a pipe connected to the subprocess named in {{CMDLINE}}. If294{{PROC}} returns normally, the pipe is closed and any result values295are returned.296297==== close-input-pipe298==== close-output-pipe299300<procedure>(close-input-pipe PORT)</procedure><br>301<procedure>(close-output-pipe PORT)</procedure>302303Closes the pipe given in {{PORT}} and waits until the connected304subprocess finishes. The exit-status code of the invoked process305is returned.306307==== create-pipe308309<procedure>(create-pipe)</procedure>310311The fundamental pipe-creation operator. Calls the C function312{{pipe()}} and returns 2 values: the file-descriptors of the input-313and output-ends of the pipe.314315On Windows, there is an optional parameter {{MODE}}, which defaults316to {{open/binary | open/noinherit}}. This can be {{open/binary}} or317{{open/text}}, optionally or'ed with {{open/noinherit}}.318319320==== open-input-pipe321322<procedure>(open-input-pipe CMDLINE [MODE])</procedure>323324Spawns a subprocess with the command-line string {{CMDLINE}} and325returns a port, from which the output of the process can be read. If326{{MODE}} is specified, it should be the keyword {{#:text}}327(the default) or {{#:binary}}.328329==== open-output-pipe330331<procedure>(open-output-pipe CMDLINE [MODE])</procedure>332333Spawns a subprocess with the command-line string {{CMDLINE}} and334returns a port. Anything written to that port is treated as the input335for the process. If {{MODE}} is specified, it should be the keyword336{{#:text}} (the default) or {{#:binary}}.337338==== pipe/buf339340<constant>pipe/buf</constant>341342This variable contains the maximal number of bytes that can be written343atomically into a pipe or FIFO.344345==== with-input-from-pipe346==== with-output-to-pipe347348<procedure>(with-input-from-pipe CMDLINE THUNK [MODE])</procedure><br>349<procedure>(with-output-to-pipe CMDLINE THUNK [MODE])</procedure>350351Temporarily set the value of352{{current-input-port/current-output-port}} to a port for a353pipe connected to the subprocess named in {{CMDLINE}} and call354the procedure {{THUNK}} with no arguments. After {{THUNK}}355returns normally the pipe is closed and the standard input-/output port356is restored to its previous value and any result values are returned.357358<enscript highlight=scheme>359(with-output-to-pipe360 "gs -dNOPAUSE -sDEVICE=jpeg -dBATCH -sOutputFile=signballs.jpg -g600x600 -q -"361 (lambda ()362 (print #<<EOF363 %!IOPSC-1993 %%Creator: HAYAKAWA Takashi<xxxxxxxx@xx.xxxxxx.xx.xx>364 /C/neg/d/mul/R/rlineto/E/exp/H{{cvx def}repeat}def/T/dup/g/gt/r/roll/J/ifelse 8365 H/A/copy(z&v4QX&93r9AxYQOZomQalxS2w!!O&vMYa43d6r93rMYvx2dca!D&cjSnjSnjjS3o!v&6A366 X&55SAxM1CD7AjYxTTd62rmxCnTdSST0g&12wECST!&!J0g&D1!&xM0!J0g!l&544dC2Ac96ra!m&3A367 F&&vGoGSnCT0g&wDmlvGoS8wpn6wpS2wTCpS1Sd7ov7Uk7o4Qkdw!&Mvlx1S7oZES3w!J!J!Q&7185d368 Z&lx1CS9d9nE4!k&X&MY7!&1!J!x&jdnjdS3odS!N&mmx1C2wEc!G&150Nx4!n&2o!j&43r!U&0777d369 ]&2AY2A776ddT4oS3oSnMVC00VV0RRR45E42063rNz&v7UX&UOzF!F!J![&44ETCnVn!a&1CDN!Y&0M370 V1c&j2AYdjmMdjjd!o&1r!M){( )T 0 4 3 r put T(/)g{T(9)g{cvn}{cvi}J}{($)g[]J}J371 cvx}forall/moveto/p/floor/w/div/S/add 29 H[{[{]setgray fill}for Y}for showpage372 EOF373 ) ) )374</enscript>375376=== Windows specific notes377378Use of UTF8 encoded strings for pathnames is not supported. Windows379uses a 16-bit UNICODE encoding with special system calls for380wide-character support. Only single-byte string encoding can be used.381382---383Previous: [[Module (chicken pretty-print)]]384385Next: [[Module (chicken process signal)]]